package com.hatic.process;

import java.util.Map;

import org.jxstar.dao.DaoParam;
import org.jxstar.service.BusinessObject;
import org.jxstar.util.StringUtil;

import com.hatic.money.PlanMoneyBO;

/**
 * 项目金额处理类：
 * 负责处理项目中的合同金额反馈、对应投资计划中的合同金额反馈；
 * 负责处理项目中的已付款金额反馈、对应投资计划中的已付款金额反馈；
 *
 * @author TonyTan
 * @version 1.0, 2011-10-29
 */
public class ProjectMoneyBO extends BusinessObject {
	private static final long serialVersionUID = 1L;
	
	/**
	 * 检查新合同金额是否超项目批复金额，超支判断：项目已签合同金额+新合同金额 > 项目批复金额
	 * @param projectId -- 项目ID
	 * @param money -- 合同金额
	 * @return
	 */
	public boolean checkContractMoney(String projectId, double money) {
		Map<String,String> pmData = queryProject(projectId);
		if (pmData.isEmpty()) {
			setMessage("没有找到项目信息！");
			return false;
		}
		//已签合同金额
		String htmoney = pmData.get("contract_money");
		//项目批复金额
		String lxmoney = pmData.get("project_money");
		
		double htnum = StringUtil.tonum(htmoney) + money;
		if (htnum > StringUtil.tonum(lxmoney)) {
			setMessage("项目合同总金额  > 项目批复金额！");
			return false;
		}
		
		return true;
	}

	/**
	 * 累加项目中的合同金额数
	 * @param projectId -- 项目ID
	 * @param money -- 合同金额
	 * @return
	 */
	public boolean addContractMoney(String projectId, double money) {
		//更新项目中的合同金额
		if (!addProjectMoney(projectId, money, "contract_money")) return false;
		
		String planId = getValidPlanId(projectId);
		if (planId == null || planId.length() == 0) {
			
			//由于项目包没有对应的投资计划，所以合同提交时不存在投资计划不报错
			//setMessage("没有找到项目对应的投资计划！");
			return true;
		} else {
			PlanMoneyBO planbo = new PlanMoneyBO();
			if (!planbo.addContractMoney(planId, money)) {
				setMessage("更新项目投资计划中的合同金额出错！");
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * 累加项目中的已付款金额数
	 * @param projectId -- 项目ID
	 * @param money -- 付款金额
	 * @return
	 */
	public boolean addPayMoney(String projectId, double money) {
		//更新项目中的已付款金额
		if (!addProjectMoney(projectId, money, "pay_money")) return false;
		
		String planId = getValidPlanId(projectId);
		if (planId == null || planId.length() == 0) {
			setMessage("没有找到项目对应的投资计划！");
			return false;
		} else {
			PlanMoneyBO planbo = new PlanMoneyBO();
			if (!planbo.addPayMoney(planId, money)) {
				setMessage("更新项目投资计划中的已付款金额出错！");
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * 累加项目中的结算金额数
	 * @param projectId -- 项目ID
	 * @param money -- 结算金额
	 * @return
	 */
	public boolean addCostMoney(String projectId, double money) {
		//更新项目中的结算金额
		if (!addProjectMoney(projectId, money, "cost_money")) return false;
		
		String planId = getValidPlanId(projectId);
		if (planId == null || planId.length() == 0) {
			setMessage("没有找到项目对应的投资计划！");
			return false;
		} else {
			PlanMoneyBO planbo = new PlanMoneyBO();
			if (!planbo.addCostMoney(planId, money)) {
				setMessage("更新项目投资计划中的结算金额出错！");
				return false;
			}
		}
		
		return true;
	}
	
	//moneyField -- 金额字段: cost_money, pay_money, contract_money
	private boolean addProjectMoney(String projectId, double money, String moneyField) {
		String sql = "update project_base set "+ moneyField +" = nvl("+ moneyField +",0) + ? where project_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addDoubleValue(Double.toString(money));
		param.addStringValue(projectId);
		
		if (!_dao.update(param)) {
			setMessage("项目的金额更新出错！");
			return false;
		}
		
		return updateParentMoney(projectId, moneyField);
	}
	
	//更新父项目的金额
	private boolean updateParentMoney(String projectId, String moneyField) {
		String parentId = getParentId(projectId);
		if (parentId.length() == 0) return true;
		
		//取子项目的合计金额
		double money = getSubMoney(parentId, moneyField);
		if (money == 0) {
			setMessage("子项目的合计金额为0，不需要更新！");
			return false;
		}
		
		if (!updateMoney(parentId, money, moneyField)) {
			setMessage("父项目的金额更新出错！");
			return false;
		}
		
		return true;
	}
	
	/**
	 * 根据项目ID查找有效的投资计划ID：同一个项目会存在多个投资计划，
	 * 但只有一个投资计划是有效的，其它投资计划是被结转的。
	 * @param projectId -- 项目ID
	 * @return
	 */
	private String getValidPlanId(String projectId) {
		//money_contract, money_pay
		String sql = "select plan_id from money_plan where plan_status < '71' and project_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(projectId);
		
		Map<String, String> mpData = _dao.queryMap(param);
		if (mpData.isEmpty()) return "";
		
		return mpData.get("plan_id");
	}
	
	//查询项目信息
	private Map<String,String> queryProject(String projectId) {
		String sql = "select * from project_base where project_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(projectId);
		
		return _dao.queryMap(param);
	}
	
	//取父项目ID
	private String getParentId(String projectId) {
		String sql = "select project_parentid from project_base where project_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(projectId);
		
		Map<String,String> mpData = _dao.queryMap(param);
		return mpData.get("project_parentid");
		
	}
	
	//汇总指定金额字段的值
	private double getSubMoney(String parentId, String moneyField) {
		String sql = "select sum("+ moneyField +") as sumdata from project_base where project_parentid = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentId);
		
		Map<String,String> mpData = _dao.queryMap(param);
		double money = StringUtil.tonum(mpData.get("sumdata"));
		
		return money;
	}
	
	//更新父项目的金额
	private boolean updateMoney(String parentId, double money, String moneyField) {
		String sql = "update project_base set "+ moneyField +" = ? where project_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addDoubleValue(Double.toString(money));
		param.addStringValue(parentId);
		
		return _dao.update(param);
	}
}
